﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Text;
using System.Threading;
using AT.IBMS.Framework.Tools;

namespace AT.IBMS.Framework.Logging
{

    /// <summary>
    /// 日志实体类型。
    /// </summary>
    public class LogEntry
    {

        private string id;
        private string message;
        private string title;
        private IList<string> categories;
        private int priority;
        private int eventId;
        private TraceEventType severity;
        private string machineName;
        private DateTime timeStamp;
        private IDictionary<string, string> extendedProperties;
        private string appDomainName;
        private string processId;
        private string processName;
        private string threadName;

        /// <summary>
        /// 获取日志的新实例。
        /// </summary>
        public LogEntry()
        {
            id = FrameworkManager.Tool.CreateNewId();
            categories = new List<string>();
            priority = -1;
            severity = TraceEventType.Information;
            machineName = Environment.MachineName;
            timeStamp = DateTime.Now;
            extendedProperties = new Dictionary<string, string>();
            appDomainName = AppDomain.CurrentDomain.FriendlyName;
            processId = Process.GetCurrentProcess().Id.ToString();
            processName = Process.GetCurrentProcess().ProcessName;
            threadName = Thread.CurrentThread.Name;
        }

        public LogEntry(
            string message,
            ICollection<string> categories,
            int priority, int eventId,
            TraceEventType severity,
            string title,
            IDictionary<string, string> properties)
            : this()
        {

            if (message == null)
            {
                throw new ArgumentNullException("message");
            }

            if (categories == null)
            {
                throw new ArgumentNullException("categories");
            }

            this.Message = message;
            this.Priority = priority;
            this.EventId = eventId;
            this.Severity = severity;
            this.Title = title;

            foreach (string item in categories)
            {
                AppendCategory(item);
            }

            if (properties != null)
            {
                foreach (KeyValuePair<string, string> item in properties)
                {
                    ExtendedProperties.Add(item);
                }
            }

        }

        public LogEntry(
            string message,
            string category,
            int priority, int eventId,
            TraceEventType severity,
            string title,
            IDictionary<string, string> properties)
            : this(
            message,
            BuildCategoriesCollection(category),
            priority,
            eventId,
            severity,
            title,
            properties)
        {

        }

        #region 日志属性。

        /// <summary>
        /// 日志的唯一编码。
        /// </summary>
        public string Id
        {
            get
            {
                return id;
            }
        }

        /// <summary>
        /// 获取或设置日志信息。
        /// </summary>
        public string Message
        {
            get
            {
                return message;
            }
            set
            {
                message = value;
            }
        }

        /// <summary>
        /// 获取或设置日志的标题。
        /// </summary>
        public string Title
        {
            get
            {
                return title;
            }
            set
            {
                title = value;
            }
        }

        /// <summary>
        /// 获取日志类型的集合。
        /// </summary>
        public ReadOnlyCollection<string> Categories
        {
            get
            {
                return new ReadOnlyCollection<string>(categories);
            }
        }

        /// <summary>
        /// 获取字符串格式的日志类型的集合。（如：General,Warning,Error）
        /// </summary>
        public string CategoriesString
        {
            get
            {

                StringBuilder categoriesString;

                categoriesString = new StringBuilder();

                foreach (string item in Categories)
                {

                    if (categoriesString.Length != 0)
                    {
                        categoriesString.Append(",");
                    }

                    categoriesString.Append(item);
                }

                return categoriesString.ToString();

            }
        }

        /// <summary>
        /// 获取或设置日志优先级
        /// </summary>
        public int Priority
        {
            get
            {
                return this.priority;
            }
            set
            {
                this.priority = value;
            }
        }

        /// <summary>
        /// 获取或设置一个用于唯一标识事件的事件 ID。
        /// </summary>
        public int EventId
        {
            get
            {
                return this.eventId;
            }
            set
            {
                this.eventId = value;
            }
        }

        /// <summary>
        /// 获取或者设置引起跟踪的事件的类型。
        /// </summary>
        public TraceEventType Severity
        {
            get
            {
                return this.severity;
            }
            set
            {
                this.severity = value;
            }
        }

        /// <summary>
        /// 获取此本地计算机的 NetBIOS 名称。
        /// </summary>
        public string MachineName
        {
            get
            {
                return this.machineName;
            }
            set
            {
                this.machineName = value;
            }
        }

        /// <summary>
        /// 获取或设置日志时间。
        /// </summary>
        public DateTime TimeStamp
        {
            get
            {
                return this.timeStamp;
            }
            set
            {
                this.timeStamp = value;
            }
        }

        /// <summary>
        /// 获取扩展属性的集合。
        /// </summary>
        public IDictionary<string, string> ExtendedProperties
        {
            get
            {
                return this.extendedProperties;
            }
        }

        /// <summary>
        /// 获取字符串格式的扩展属性的集合。（格式：{key1=value1,key2=value2,key3=value3}）
        /// </summary>
        public string ExtendedPropertiesString
        {
            get
            {

                StringBuilder extendedPropertiesString;

                extendedPropertiesString = new StringBuilder();

                foreach (KeyValuePair<string, string> item in ExtendedProperties)
                {

                    if (extendedPropertiesString.Length == 0)
                    {
                        extendedPropertiesString.Append("{");
                    }
                    else
                    {
                        extendedPropertiesString.Append(",");
                    }

                    extendedPropertiesString.Append(item.Key);
                    extendedPropertiesString.Append("=");
                    extendedPropertiesString.Append(item.Value);

                }

                if (extendedPropertiesString.Length != 0)
                {
                    extendedPropertiesString.Append("}");
                }

                return extendedPropertiesString.ToString();

            }
        }

        /// <summary>
        /// 获取或设置此应用程序域的友好名称。
        /// </summary>
        public string AppDomainName
        {
            get
            {
                return this.appDomainName;
            }
            set
            {
                this.appDomainName = value;
            }
        }

        /// <summary>
        /// 获取或设置分配给进程的 ID 号。
        /// </summary>
        public string ProcessId
        {
            get
            {
                return processId;
            }
            set
            {
                processId = value;
            }
        }

        /// <summary>
        /// 获取或设置进程的名称。
        /// </summary>
        public string ProcessName
        {
            get
            {
                return processName;
            }
            set
            {
                processName = value;
            }
        }

        /// <summary>
        /// 获取或设置 .Net 线程的名称。
        /// </summary>
        public string ManagedThreadName
        {
            get
            {
                return threadName;
            }
            set
            {
                threadName = value;
            }
        }

        #endregion

        #region 日志方法。

        /// <summary>
        /// 为这个日志添加分类。
        /// </summary>
        /// <param name="categories"></param>
        public void AppendCategory(string category)
        {

            if (string.IsNullOrEmpty(category))
            {
                throw new ArgumentNullException("category");
            }

            this.categories.Add(category);
        }

        /// <summary>
        /// 清除所有已添加的日志分类。
        /// </summary>
        public void ClearCategories()
        {
            categories.Clear();
        }

        private static List<string> BuildCategoriesCollection(string category)
        {

            List<string> result;

            if (string.IsNullOrEmpty(category))
            {
                throw new ArgumentNullException("category");
            }

            result = new List<string>();
            result.Add(category);

            return result;
        }

        #endregion

    }
}
